import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

public class GameFrame {

    JFrame myFrame = new JFrame("太空侵略者");
    MyCanvas can = new MyCanvas();

    {
        myFrame.setBounds(10,10,600,600);
        myFrame.setLayout(null);
    }

    public static void main(String[] args) throws InterruptedException {
        GameFrame gameFrame =new GameFrame();
        gameFrame.run();
        gameFrame.after();


    }

    private void run() {

        can.setBounds(10,10,560,540);
        can.setBackground(new Color(221,221,221));
        can.setBackground(new Color(0,0,0));
        myFrame.add(can);
    }
    private void after() throws InterruptedException {
        myFrame.setVisible(true);
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }

}

//游戏者的画布
class MyCanvas extends Canvas {
    private boolean gameWin = false;  // 是否胜利
    private boolean gameFail = false; // 是否失败（玩家被击中）

    private boolean gameOver = false;
    private java.util.List<AlienBullet> alienBullets = new ArrayList<>();
    private BufferedImage alienBulletImage; // 外星人子弹图片

    private java.util.List<Alien> aliens = new ArrayList<>();
    private int alienDirection = 1; // 左右方向：1=右，-1=左
    private Timer alienMoveTimer;
    private BufferedImage alienImage; // 外星人图片
    private BufferedImage bulletImage;   // 子弹图片
    private java.util.List<Bullet> bullets = new ArrayList<>();
    private BufferedImage image;
    private BufferedImage offImage; // 双缓冲图像
    private Graphics offG;
    //定义玩家的初始位置
    private int x = 10;
    private int y = 500;

    // 构造方法
    public MyCanvas() {
        try {
            image = ImageIO.read(new File("src/images/player.png"));
            bulletImage = ImageIO.read(new File("src/images/shot.png"));
            alienImage = ImageIO.read(new File("src/images/alien.png"));
            alienBulletImage = ImageIO.read(new File("src/images/bomb.png"));
        } catch (IOException e) {

            throw new RuntimeException(e);
        }

        this.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                //设置x的范围
                if(e.getX() < 530){
                    x = e.getX();
                }
                y = 500;
                repaint();
            }
        });

        // 初始化双缓冲
        offImage = new BufferedImage(560, 520, BufferedImage.TYPE_INT_ARGB);
        offG = offImage.getGraphics();
        // 定时器：每 500ms 发射一颗子弹（1秒2颗）
        Timer timer = new Timer(100, e -> {
            fireBullet();
            repaint(); // 主动刷新画面
        });
        timer.start();

        //外星人
        // 初始化外星人矩阵（6行4列）
        for (int row = 0; row < 4; row++) {
            for (int col = 0; col < 6; col++) {
                int alienX = 80 + col * 30;
                int alienY = 50 + row * 20;
                Alien alien = new Alien(alienX, alienY, alienImage);
                aliens.add(alien);

                // 每个外星人有自己的定时器，随机发射子弹
                Timer alienFireTimer = new Timer(2000 + (int)(Math.random() * 1000), e -> {
                    if (alien.alive) {
                        fireAlienBullet(alien);
                    }
                });
                alienFireTimer.start();
            }
        }
        // 定时器：外星人移动
        alienMoveTimer = new Timer(20, e -> {
            moveAliens();
            checkCollisions();
            repaint();
        });
        alienMoveTimer.start();

    }
    private void fireAlienBullet(Alien alien) {
        int bulletX = alien.x + alien.image.getWidth() / 2 - alienBulletImage.getWidth() / 2;
        int bulletY = alien.y + alien.image.getHeight(); // 子弹从外星人下方开始
        alienBullets.add(new AlienBullet(bulletX, bulletY, alienBulletImage));
    }

    private void fireBullet() {
        int bulletX = x + image.getWidth() * 2 / 2 - bulletImage.getWidth() / 2;
        int bulletY = y - bulletImage.getHeight(); // 子弹从玩家头顶开始
        bullets.add(new Bullet(bulletX, bulletY, bulletImage));
    }

    //外星人
    private void moveAliens() {
        boolean changeDirection = false;

        for (Alien alien : aliens) {
            if (alien.alive) {
                alien.move(alienDirection * 2);

                // 判断是否触碰到边界
                if (alien.x <= 0 || alien.x + alien.image.getWidth() >= 560) {
                    changeDirection = true;
                }
            }
        }

        if (changeDirection) {
            alienDirection *= -1; // 反向
            for (Alien alien : aliens) {
                if (alien.alive) {
                    alien.y += 10; // 下移一行
                }
            }
        }
    }

    private void checkCollisions() {
        // 检测是否所有外星人都被消灭
        boolean allAliensDead = aliens.stream().noneMatch(alien -> alien.alive);

        if (allAliensDead && !gameOver) {
            System.out.println("所有外星人被消灭！");
            gameOver = true;
            gameWin = true;
            removeMouseMotionListeners(); // 移除鼠标监听器
            repaint(); // 刷新画面以显示“游戏胜利”
        }

        // 玩家碰撞检测
        for (AlienBullet ab : alienBullets) {
            Rectangle playerBounds = new Rectangle(x, y, image.getWidth() * 2, image.getHeight() * 3);
            if (playerBounds.contains(ab.x, ab.y)) {
                System.out.println("玩家被击中！");
                gameOver = true;
                gameFail = true;
                removeMouseMotionListeners();
                repaint();
                break;
            }
        }

        //
        for (Iterator<Bullet> it = bullets.iterator(); it.hasNext(); ) {
            Bullet b = it.next();
            for (Alien alien : aliens) {
                if (alien.alive && alien.getBounds().intersects(new Rectangle(b.x, b.y, b.image.getWidth(), b.image.getHeight()))) {
                    alien.alive = false;
                    it.remove();
                    break;
                }
            }
        }
        // 检查外星人子弹是否击中玩家
        for (AlienBullet ab : alienBullets) {
            Rectangle playerBounds = new Rectangle(x, y, image.getWidth() * 2, image.getHeight() * 3);
            if (playerBounds.contains(ab.x, ab.y)) {
                // 玩家被击中，游戏结束或重置
                // System.out.println("玩家被击中！");
                // 可以在这里添加游戏结束逻辑
                gameOver = true;
                removeMouseMotionListeners(); // 移除鼠标移动监听器
                repaint(); // 刷新画面以显示“游戏结束”
                break;
            }
        }
    }
    private void removeMouseMotionListeners() {
        for (MouseMotionAdapter listener : getListeners(MouseMotionAdapter.class)) {
            removeMouseMotionListener(listener);
        }
    }




    @Override
    public void update(Graphics g) {
        // 自定义更新方法，避免默认清屏造成的闪烁
        paint(g);
    }

    @Override
    public void paint(Graphics g) {
        if (offImage == null) return;

        // 清除上一帧
        offG.setColor(getBackground());
        offG.fillRect(0, 0, getWidth(), getHeight());
        if (gameOver) {
            // offG.setColor(Color.GREEN);
            offG.setFont(new Font("Arial", Font.BOLD, 36));
            if (gameWin) {
                offG.setColor(Color.GREEN);
                offG.drawString("Victory", 180, 260); // 胜利
            } else if (gameFail) {
                offG.setColor(Color.RED);
                offG.drawString("Failure", 180, 260); // 失败
            }

        }else {

            // 绘制新图像
            offG.drawImage(image, x, y, image.getWidth() * 2, image.getHeight() * 3, null);

            // 更新并绘制所有子弹
            for (Iterator<Bullet> it = bullets.iterator(); it.hasNext(); ) {
                Bullet b = it.next();
                b.move();
                if (b.isOffScreen()) {
                    it.remove(); // 超出范围就移除
                } else {
                    offG.drawImage(b.image, b.x, b.y, b.image.getWidth(), b.image.getHeight(), null);
                }
            }
            // 绘制外星人
            for (Alien alien : aliens) {
                if (alien.alive) {
                    offG.drawImage(alien.image, alien.x, alien.y, alien.image.getWidth(), alien.image.getHeight(), null);
                }
            }

            // g.drawImage(offImage, 0, 0, this);
            // 绘制外星人子弹
            for (Iterator<AlienBullet> it = alienBullets.iterator(); it.hasNext(); ) {
                AlienBullet ab = it.next();
                ab.move();
                if (ab.isOffScreen()) {
                    it.remove();
                } else {
                    offG.drawImage(ab.image, ab.x, ab.y, ab.image.getWidth(), ab.image.getHeight(), null);
                }
            }


        }


        // 将缓冲图像绘制到屏幕上
        g.drawImage(offImage, 0, 0, this);
    }
}

//玩家子弹
class Bullet {
    int x, y;
    BufferedImage image;

    public Bullet(int x, int y, BufferedImage image) {
        this.x = x;
        this.y = y;
        this.image = image;
    }

    public void move() {
        y -= 5; // 向上移动
    }

    public boolean isOffScreen() {
        return y + image.getHeight() < 0;
    }
}

// 外星人
class Alien {
    int x, y;
    BufferedImage image;
    boolean alive = true;

    public Alien(int x, int y, BufferedImage image) {
        this.x = x;
        this.y = y;
        this.image = image;
    }

    public void move(int dx) {
        x += dx;
    }

    public Rectangle getBounds() {
        return new Rectangle(x, y, image.getWidth()*3, image.getHeight());
    }
}

//外星人子弹
class AlienBullet {
    int x, y;
    BufferedImage image;

    public AlienBullet(int x, int y, BufferedImage image) {
        this.x = x;
        this.y = y;
        this.image = image;
    }

    public void move() {
        y += 3; // 向下移动
    }

    public boolean isOffScreen() {
        return y > 520; // 超出画布高度则判定为消失
    }
}